
import type { Server as HttpServer } from 'http';
import express from 'express';
import cors from 'cors';
import fs from 'fs';
import path from 'path';
import { ChildProcess, spawn } from 'child_process';
import { initDatabase, syncModels } from './database';
import roomRoutes from './routes/rooms';
import dycastRoutes from './routes/dycast';
import messageRoutes from './routes/messages';
import sessionRoutes from './routes/sessions';
import giftRoutes from './routes/gifts';
import recordingRoutes from './routes/recording';
import { LiveStreamManager } from './LiveStreamManager';
import {puppeteerManager} from './puppeteer-service';
import { startProxyServer } from './proxy-server';

import { MessageWrapper } from './types/MessageTypes';

// 监听新消息事件
puppeteerManager.on('newMessages', async (data: MessageWrapper) => {
  for (const message of data.messages) {
    LiveStreamManager.handleMessage(message, data.roomId);
  }
});

// 监听房间断开连接事件
puppeteerManager.on('roomDisconnected', async (data: any) => {
  const { roomId, code, reason } = data;
  console.log(`🔌 [事件] 房间 ${roomId} 断开连接 (code: ${code}, reason: ${reason})`);

  // 清理房间状态
  try {
    await LiveStreamManager.handleRoomDisconnected(roomId);
  } catch (error) {
    console.error(`处理房间断开连接失败:`, error);
  }
});

// 监听连接错误事件
puppeteerManager.on('connectionError', async (data: any) => {
  const { roomId, error } = data;
  console.error(`❌ [事件] 房间 ${roomId} 连接错误: ${error}`);
});

// 监听连接失败事件
puppeteerManager.on('connectionFailed', async (data: any) => {
  const { roomId, error } = data;
  console.error(`❌ [事件] 房间 ${roomId} 连接失败: ${error}`);

  // 清理房间状态
  try {
    await LiveStreamManager.handleRoomDisconnected(roomId);
  } catch (error) {
    console.error(`处理房间连接失败后清理失败:`, error);
  }
});

// 创建Express应用
const app = express();
let proxyServer: HttpServer | null = null;

 
// 启动 DouyinLiveRecorder Python 进程
const DOUYIN_RECORDER_SCRIPT = path.resolve(__dirname, '..', '..', 'DouyinLiveRecorder', 'main.py');
let douyinRecorderProcess: ChildProcess | null = null;

function stopDouyinRecorder() {
  if (douyinRecorderProcess && !douyinRecorderProcess.killed) {
    const signal = process.platform === 'win32' ? 'SIGINT' : 'SIGTERM';
    try {
      douyinRecorderProcess.kill(signal);
    } catch (error) {
      console.error('[DouyinRecorder] 结束进程失败', error);
    }
  }
}

function stopProxyServer() {
  if (proxyServer) {
    proxyServer.close(() => {
      console.log('[Proxy] 代理服务器已关闭');
    });
    proxyServer = null;
  }
}

function launchDouyinRecorder() {
  if (!fs.existsSync(DOUYIN_RECORDER_SCRIPT)) {
    console.warn(`[DouyinRecorder] 未找到脚本: ${DOUYIN_RECORDER_SCRIPT}`);
    return;
  }
  if (douyinRecorderProcess && !douyinRecorderProcess.killed) {
    console.log(`[DouyinRecorder] 已在运行 (PID: ${douyinRecorderProcess.pid})`);
    return;
  }

  const pythonExecutable = process.env.PYTHON_PATH || process.env.PYTHON || (process.platform === 'win32' ? 'python' : 'python3');

  try {
    // 为DouyinRecorder创建环境变量，移除代理设置（视频下载不需要代理）
    const recorderEnv = { ...process.env };
    delete recorderEnv.HTTP_PROXY;
    delete recorderEnv.HTTPS_PROXY;
    delete recorderEnv.http_proxy;
    delete recorderEnv.https_proxy;

    douyinRecorderProcess = spawn(pythonExecutable, ['-u', DOUYIN_RECORDER_SCRIPT], {
      cwd: path.dirname(DOUYIN_RECORDER_SCRIPT),
      stdio: ['ignore', 'pipe', 'pipe'],
      env: {
        ...recorderEnv,
        PYTHONIOENCODING: 'utf-8',
      },
    });

    console.log(`[DouyinRecorder] 已启动进程 (PID: ${douyinRecorderProcess.pid})`);

    douyinRecorderProcess.stdout?.setEncoding('utf8');
    douyinRecorderProcess.stdout?.on('data', (chunk: string) => {
      process.stdout.write(`[DouyinRecorder] ${chunk}`);
    });

    douyinRecorderProcess.stderr?.setEncoding('utf8');
    douyinRecorderProcess.stderr?.on('data', (chunk: string) => {
      process.stderr.write(`[DouyinRecorder][stderr] ${chunk}`);
    });

    douyinRecorderProcess.on('exit', (code, signal) => {
      console.log(`[DouyinRecorder] 进程退出 code=${code} signal=${signal}`);
      douyinRecorderProcess = null;
    });

    douyinRecorderProcess.on('error', (error) => {
      console.error('[DouyinRecorder] 启动失败', error);
    });
  } catch (error) {
    console.error('[DouyinRecorder] 调用 spawn 失败', error);
  }
}

const terminationSignals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM'];
if (process.platform === 'win32') {
  terminationSignals.push('SIGBREAK');
}

terminationSignals.forEach((signal) => {
  process.on(signal, () => {
    stopDouyinRecorder();
    stopProxyServer();
    process.exit();
  });
});

process.on('exit', () => {
  stopDouyinRecorder();
  stopProxyServer();
});

// 初始化数据库



// 中间件
app.use(cors()); // 启用CORS
app.use(express.json());

// 路由
app.use('/api/rooms', roomRoutes);
app.use('/api/dycast', dycastRoutes);
app.use('/api/messages', messageRoutes);
app.use('/api/sessions', sessionRoutes);
app.use('/api/gifts', giftRoutes);
app.use('/api/recording', recordingRoutes);
app.get("/health", function (req, res) {
  res.end("ok");
});

// 启动服务器
async function startServer() {
  try {
    // 初始化数据库连接
    await initDatabase();
    console.log('✅ 数据库初始化完成');

    // 同步数据库模型
    await syncModels(); // 数据库模型同步
    console.log('✅ 数据库模型同步完成');

    // 清空 URL_config.ini（避免 DouyinLiveRecorder 读取旧数据）
    LiveStreamManager.clearUrlConfig();

    const PORT = 3000;
    const PROXY_PORT = PORT + 1;
    app.listen(PORT, () => {
      console.log(`🚀 服务器启动成功，端口: ${PORT}`);
      console.log(`📡 API地址: http://localhost:${PORT}/api`);
    });

    if (!proxyServer) {
      proxyServer = startProxyServer(PROXY_PORT);
      console.log(`🛰️ 代理服务器运行中: http://localhost:${PROXY_PORT}`);
    }

  // 在清空配置文件后再启动录制程序
  launchDouyinRecorder();
    
    // 根据环境变量决定是否自动启动轮询录屏
    const autoRecordRaw = (process.env.auto_record ?? 'false').toString().trim().toLowerCase();
    const autoRecord = autoRecordRaw === 'true' || autoRecordRaw === '1' || autoRecordRaw === 'yes';
    if (autoRecord) {
      setTimeout(() => {
        console.log('🔄 启动轮询监听模块...');
        LiveStreamManager.startPolling();
      }, 5000); // 延迟5秒启动，确保其他组件都已初始化完成
    } else {
      console.log('⏸️ 已禁用自动轮询录屏（auto_record=false），可通过 API 或手动调用启动');
    }

  } catch (error) {
    console.error('❌ 服务器启动失败:', error);

  }
}

startServer();
